package ad.android.service.impl;

import java.io.IOException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import ad.android.dao.IAdDao;
import ad.android.dto.AdDto;
import ad.android.dto.RequestAdJsonDto;
import ad.android.dto.cond.AdCondition;
import ad.android.dto.cond.SearchCondition;
import ad.android.exception.DaoException;
import ad.android.exception.ServiceException;
import ad.android.model.Ad;
import ad.android.model.Application;
import ad.android.service.IAdService;
import ad.android.service.IApplicationService;
import ad.android.service.base.BaseService;
import ad.android.util.Base64;
import ad.android.util.Constants;
import ad.android.util.FileReaderUtil;
import ad.android.util.ProbabilityUtil;

public class AdServiceImpl extends BaseService implements IAdService {
	private IAdDao adDao;
	private IApplicationService appService;
	
	@Override
	public AdDto findAd(RequestAdJsonDto requestAdJsonDto)
			throws ServiceException {
		try {
			AdDto adDto = new AdDto();
			
			Ad ad = getRandomAd();
			Application app = appService.findApplicationByLicenseKey( requestAdJsonDto.getLicensekey() );
			if( app != null && app.getAdRefreshTime() != null){
				adDto.setRefreshTime( app.getAdRefreshTime() );
			}else{
				throw new ServiceException("get App error.");
			}
			
			adDto.setAdId( String.valueOf(ad.getId()) );
			String html = getAdHtml("tmpl.html", requestAdJsonDto,ad,app);
			String encodeHtml = Base64.encodeToString(html.getBytes(), false);
			adDto.setAdHtml( encodeHtml );
//			adDto.setAdHtml(html);
//			System.out.println( new String(Base64.decode(encodeHtml)) );
			adDto.setAdWidth( requestAdJsonDto.getScreenWidth() );
			adDto.setAdHeight( requestAdJsonDto.getScreenHeight()/10 );
			
			return adDto;
		} catch (Exception e) {
			logDebug("findAd", e);
			throw new ServiceException(e);
		}

	}

	/**
	 * 根据概率获取广告ID
	 * @return
	 */
	private Ad getRandomAd() {
		try {
			float floatWeight = ProbabilityUtil.getRandomFloatWeight();
			int intWeight = ProbabilityUtil.getIntWeight(floatWeight);
			
			int intWeightAdNum = findAdNumByWeight(intWeight);
			
			int start = ProbabilityUtil.getRandomInt(intWeightAdNum);
			
			AdCondition cond = new AdCondition();
			cond.setWeigth(intWeight);
			SearchCondition sCond = new SearchCondition();
			sCond.setStart(start);
			sCond.setLimit(Constants.NUM_1);
			List<Ad> adList = adDao.findAdByCondition(cond,sCond);
			if(adList.size() == 0){
				throw new ServiceException("getRandomAd error.");
			}
			return adList.get(0);
		} catch (DaoException e) {
			log.error("getRandomAd",e);
			throw new ServiceException(e);
		}
	}

	/**
	 * 查找权值为intWeight的广告数
	 * @param intWeight
	 * @return
	 */
	private int findAdNumByWeight(int intWeight) {
		try {
			return adDao.findAdNumByWeight(intWeight);
		} catch (DaoException e) {
			log.error("findAdNumByWeight",e);
			throw new ServiceException(e);
		}
	}

	private String getAdHtml(String tmplFileName,
			RequestAdJsonDto requestAdJsonDto, Ad ad,Application app) throws ServiceException {
		try {
			// 读取HTML
			String html = FileReaderUtil.readTmplHtml(tmplFileName);

			html = setHtmlValue(html, "title", app.getAppName());
			html = setHtmlValue(html, "width",
					String.valueOf(requestAdJsonDto.getScreenWidth()));
			html = setHtmlValue(html, "height",
					String.valueOf(requestAdJsonDto.getScreenHeight()/10));
			
//			html = setHtmlValue(html, "clickUrl", "redir://click");
			html = setHtmlValue(html, "clickUrl", ad.getAdClickLink());
			
//			html = setHtmlValue(html, "imgUrl", "http://www.a.com/i.jpg");
			html = setHtmlValue(html, "imgUrl", ad.getAdImgLink());
			
			logDebug("HTML:" + html);
			return html;
		} catch (IOException e) {
			logDebug("getAdHtml", e);
			throw new ServiceException(e);
		}

	}

	private String setHtmlValue(String html, String key, String value) {
		Pattern pattern = Pattern.compile("\\{\\{= " + key + "\\}\\}");
		Matcher matcher = pattern.matcher(html);
		html = matcher.replaceFirst(value);
		return html;
	}

	@Override
	public Ad findAd(Long adId) throws ServiceException {
		try {
			return adDao.findAdById(adId);
		} catch (DaoException e) {
			logDebug("findAd", e);
			throw new ServiceException(e);
		}
	}

	public IAdDao getAdDao() {
		return adDao;
	}

	public void setAdDao(IAdDao adDao) {
		this.adDao = adDao;
	}

	public IApplicationService getAppService() {
		return appService;
	}

	public void setAppService(IApplicationService appService) {
		this.appService = appService;
	}

}
